<template>
    <div>
        <Button type="primary" ghost icon="md-add" @click="handleOpenCreate">添加角色</Button>
        <Button @click="handleDeleteMultiple" type="error" ghost icon="md-trash" class="ivu-ml-8" v-show="selectedRoleData.length">批量删除</Button>
        <div class="ivu-inline-block ivu-fr">
            <Dropdown @on-click="handleChangeTableSize" trigger="click">
                <Tooltip class="ivu-ml" content="密度" placement="top">
                    <i-link>
                        <Icon type="md-list" />
                    </i-link>
                </Tooltip>
                <DropdownMenu slot="list">
                    <DropdownItem name="default" :selected="tableSize === 'default'">默认</DropdownItem>
                    <DropdownItem name="large" :selected="tableSize === 'large'">宽松</DropdownItem>
                    <DropdownItem name="small" :selected="tableSize === 'small'">紧凑</DropdownItem>
                </DropdownMenu>
            </Dropdown>
            <Tooltip class="ivu-ml" :content="tableFullscreen ? '退出全屏' : '全屏'" placement="top">
                <i-link @click.native="handleFullscreen">
                    <Icon :custom="tableFullscreen ? 'i-icon i-icon-exit-full-screen' : 'i-icon i-icon-full-screen'" />
                </i-link>
            </Tooltip>
            <Tooltip class="ivu-ml" content="刷新" placement="top">
                <i-link @click.native="handleRefresh">
                    <Icon custom="i-icon i-icon-refresh" />
                </i-link>
            </Tooltip>
            <Dropdown trigger="click">
                <Tooltip class="ivu-ml" content="列设置" placement="top">
                    <i-link>
                        <Icon type="md-options" />
                    </i-link>
                </Tooltip>
                <DropdownMenu slot="list">
                    <div class="ivu-p-8">列展示</div>
                    <Divider size="small" class="ivu-mt-8 ivu-mb-8" />
                    <template  v-for="item in columns">
                        <li class="ivu-dropdown-item" :key="item.title" v-if="item.title" @click="item.show = !item.show">
                            <Checkbox v-model="item.show"></Checkbox>
                            <span>{{ item.title }}</span>
                        </li>
                    </template>
                </DropdownMenu>
            </Dropdown>
        </div>
        <Table
            ref="table"
            :columns="tableColumns"
            :data="list"
            :loading="loading"
            :size="tableSize"
            class="ivu-mt"
            @on-sort-change="handleSortChange"
            @on-select="handleSelect"
            @on-select-cancel="handleSelectCancel"
            @on-select-all="handleSelectAll"
            @on-select-all-cancel="handleClearSelect">
            <template slot-scope="{ row }" slot="system">
                  {{getSystemNameBy(row.systemId)}}
            </template>
            <template slot-scope="{ row }" slot="action">
                <div @click.stop.prevent>
                    <a type="text" @click="handleOpenMenu(row.id)">授权</a>
                    <Divider type="vertical" />
                    <a type="text" @click="handleEdit(row.id)">编辑</a>
                    <Divider type="vertical" />
                    <a type="text" @click="handleDelete(row.id)">删除</a>
                </div>
            </template>
        </Table>
        <div class="ivu-mt ivu-text-center">
            <Page
                :total="pageNation.total"
                :page-size-opts="pageSizeOpts"
                :current.sync="pageNation.pageNumber"
                show-total
                show-sizer
                show-elevator
                :page-size="pageNation.pageSize"
                @on-change="handleChangePage"
                @on-page-size-change="handleChangePageSize"
            />
        </div>
        <Drawer
                :styles="drawer.styles"
                v-model="drawer.show"
                :title="drawer.type === 'edit' ? '编辑角色' : '添加角色'"
                :before-close="handleCloseEdit"
                :transfer="false"
                width="360"
        >
            <Form
                    v-if="roleInfo && roleInfoReady"
                    ref="roleInfoForm"
                    :model="roleInfo"
                    :rules="roleInfoRules"
                    label-position="top"
                    label-colon
                    hide-required-mark>
                <FormItem prop="roleName" label="角色名称">
                    <Input v-model="roleInfo.roleName" placeholder="请输入角色名称，必填" />
                </FormItem>
                <FormItem prop="roleCode" label="角色编码">
                    <Input v-model="roleInfo.roleCode" placeholder="请输入角色编码，必填" />
                </FormItem>
                <FormItem prop="roleDescrib" label="角色描述">
                    <Input v-model="roleInfo.roleDescrib" placeholder="角色描述" />
                </FormItem>
            </Form>
            <div class="page-sys-role-drawer-footer" v-if="drawer.type === 'edit'">
                <Button type="primary" @click="handleSubmitEdit" :loading="submitting">提交</Button>
            </div>
            <div class="page-sys-role-drawer-footer" v-if="drawer.type === 'new'">
                <Button type="primary" @click="handleSubmitNew" :loading="submitting">提交</Button>
            </div>
        </Drawer>
        <Modal v-model="modal.show" :title="roleInfo ? '分配 ' + roleInfo.roleName + ' 权限' : ''" :transfer="false" :styles="{top: modalTop+'px',width:'800px'}">
            <template>
                <Tabs size="small">
                    <TabPane label="菜单资源">
                        <div :style="{height:modalHeight+'px',overflow: 'auto'}">
                            <ButtonGroup :style="{margin:'10px'}">
                                <Button type="primary" ghost v-show="!toggleExpand" @click="handleToggleExpandAll(true)">全部展开</Button>
                                <Button type="primary" ghost v-show="toggleExpand" @click="handleToggleExpandAll(false)">全部收起</Button>
                                <Button type="primary" ghost v-show="!toggleSelectAll" @click="handleToggleSelectAll(true)">全部选择</Button>
                                <Button type="primary" ghost v-show="toggleSelectAll" @click="handleToggleSelectAll(false)">全部取消</Button>
                            </ButtonGroup>
                            <Divider size="small" class="ivu-mt-8 ivu-mb-8" />
                            <Tree :data="roleMenuList" show-checkbox check-strictly check-directly @on-check-change="handleCheckNode" />
                        </div>
                    </TabPane>
                </Tabs>
                <div slot="footer">
                    <Button type="primary" :loading="submitting" @click="handleSubmitPermission">提交</Button>
                </div>
          </template>
        </Modal>
    </div>
</template>
<script>
    import { cloneDeep } from 'lodash';
    export default {
        data () {
            return {
                columns: [
                    {type: 'selection',minWidth: 60,align: 'center',show: true},
                    {title: 'ID',key: 'id',minWidth: 140,show: false},
                    {title: '角色名称',key: 'roleName',minWidth: 140,show: true},
                    {title: '角色编码',key: 'roleCode',minWidth: 140,show: true},
                    {title: '角色描述',key: 'roleDescrib',minWidth: 140,show: true},
                    {title: '创建时间',key: 'createTime',minWidth: 200,show: true},
                    {title: '更新时间',key: 'updateTime',minWidth: 200,show: true},
                    {title: '操作',key: 'action',slot: 'action',minWidth: 200,align: 'center',fixed: 'right',show: true}
                ],
                loading: false,
                list: [],
                selectedRoleData: [],
                sortType: 'normal', // 当前排序类型，可选值为：normal（默认） || asc（升序）|| desc（降序）,
                sortKey: '', // 排序列的 key
                tableSize: 'default',
                tableFullscreen: false,
                drawer: {
                    show: false,
                    type: 'edit', // edit || new
                    styles: {
                        height: 'calc(100% - 55px)',
                        overflow: 'auto',
                        paddingBottom: '53px',
                        position: 'static'
                    }
                },
                roleInfo: null,
                roleInfoRules: {
                    name: [
                        { required: true, message: '请输入角色名称', trigger: 'blur' }
                    ]
                },
                roleInfoString: '',
                roleInfoReady: true,
                submitting: false,
                modal: {
                    show: false
                },
                menuList: [],
                roleMenuList: [],
                toggleExpand: true,
                toggleSelectAll: false,
                pageSizeOpts:[10,30,50,100],
                pageNation:{total:0,pageSize:10,pageNumber:1},
                //数据库获取的菜单数据列表
                menuDataList:[],
                modalTop:200,
                modalHeight:0,
                selectedMenuData:[],
                selectedMenuIds:[],
                roleParam: {}
            }
        },
        computed: {
            // 动态设置列
            tableColumns () {
                const columns = [...this.columns];
                return columns.filter(item => item.show);
            },
            lang () {
                return {
                    'en-US': {
                        cancel: 'cancel',
                        confirmDelete: 'confirm delete?',
                        confirm: 'confirm'
                    },
                    'zh-CN': {
                        cancel: '取消',
                        confirmDelete: '确认删除？',
                        confirm: '确认'
                    }
                }[this.G_Locale]
            }
        },
        methods: {
            //窗体监听方法
            initElementHeight() {
                //然后监听window的resize事件
                const _this = this;
                _this.calcElementHeight(_this);
                window.onresize = function temp() {
                    _this.calcElementHeight(_this);
                };
            },
            calcElementHeight(_this){
                _this.$nextTick(() => {
                    this.modalHeight = document.documentElement.clientHeight - this.modalTop*2-80;
                });
            },
            //获取角色列信息
            getData () {
                if (this.loading) return;
                this.loading = true;
                // 下面的 params 是获取的表单查询参数
                this.pageNation.total = 0;
                this.list = [];
                let condition = "";
                const params = this.$parent.$parent.$refs.form.data;
                if (params.roleName != null && params.roleName != "") {
                    condition += "roleName like '" + params.roleName + "'";
                }
                if (params.roleCode != null && params.roleCode != "") {
                    condition += "roleCode like '" + params.roleCode + "'";
                }

                this.$api.Role.queryByPage(this.pageNation.pageNumber, this.pageNation.pageSize, {condition}).then(res => {
                    this.list = cloneDeep(res.records);
                    this.pageNation.total = res.recordCount;
                    this.pageNation.pageNumber = res.pageNumber;
                    this.pageNation.pageSize = res.pageSize;
                }).finally(() => {
                    this.loading = false;
                });
            },
            // 改变表格尺寸
            handleChangeTableSize (size) {
                this.tableSize = size;
            },
            // 表格全屏
            handleFullscreen () {
                this.tableFullscreen = !this.tableFullscreen;
                this.$emit('on-fullscreen', this.tableFullscreen);
            },
            // 刷新表格数据
            handleRefresh () {
                this.getData();
            },
            // 切换页码
            handleChangePage (page) {
                this.pageNation.pageNumber = page;
                this.getData();
            },
            // 切换每页条数
            handleChangePageSize (size) {
                this.pageNation.pageNumber = 1;
                this.pageNation.pageSize = size;
                this.getData();
            },
            // 排序
            handleSortChange ({ key, order }) {
                this.pageNation.pageNumber = 1;
                this.sortType = order;
                this.sortKey = key;
                this.getData();
            },
            // 选中一项，将数据添加至已选项中
            handleSelect (selection, row) {
                this.selectedRoleData.push(row);
            },
            // 取消选中一项，将取消的数据从已选项中删除
            handleSelectCancel (selection, row) {
                const index = this.selectedRoleData.findIndex(item => item.id === row.id);
                this.selectedRoleData.splice(index, 1);
            },
            // 当前页全选时，判断已选数据是否存在，不存在则添加
            handleSelectAll (selection) {
                selection.forEach(item => {
                    if (this.selectedRoleData.findIndex(i => i.id === item.id) < 0) {
                        this.selectedRoleData.push(item);
                    }
                });
            },
            // 清空所有已选项
            handleClearSelect () {
                this.selectedRoleData = [];
            },
            // 查找单一角色信息
            handleGetRole (id) {
                return this.list.find(item => item.id === id);
            },
            // 删除
            handleDelete (id) {
              if (this.loading) return;
                let _this = this;
                this.$Modal.confirm({
                    title: this.lang['confirmDelete'],
                    cancelText: this.lang['cancel'],
                    content: `您确认要删除角色 <strong>${this.handleGetRole(id).roleName}</strong>？`,
                    onOk () {
                        _this.deleteRole(id);
                    }
                })
            },
            //根据职位ID删除职位
            deleteRole(id){
                this.$api.Role.deleteById(id).then(res => {
                    this.submitting = false;
                    this.drawer.show = false;
                    this.$Modal.remove();
                    this.handleClearSelect();
                    this.handleChangePage(1);
                })
            },

            // 批量删除
            handleDeleteMultiple() {
                if (this.loading) return;
                const ids = this.selectedRoleData.map(item => item.id);
                const names = this.selectedRoleData.map(item => item.roleName);
                let _this = this;
                this.$Modal.confirm({
                    title: this.lang['confirmDelete'],
                    cancelText: this.lang['cancel'],
                    content: `您确认要删除角色 <strong>${names}</strong>？`,
                    onOk() {
                        _this.deleteRoleMultiple(ids);
                    }
                })
            },
            //批量删除
            deleteRoleMultiple(ids){
                this.$api.Role.deleteByIds(ids).then(res => {
                    this.submitting = false;
                    this.drawer.show = false;
                    this.$Modal.remove();
                    this.handleClearSelect();
                    this.handleChangePage(1);
                })
            },
            // 编辑
            handleEdit (id) {
                this.roleInfo = cloneDeep(this.handleGetRole(id));
                this.roleInfoString = JSON.stringify(this.roleInfo);
                this.drawer.type = 'edit';
                this.drawer.show = true;
                this.handleInitRoleInfoForm();
            },
            handleInitRoleInfoForm () {
                this.roleInfoReady = false;
                this.$nextTick(() => {
                    this.roleInfoReady = true;
                });
            },
            // 关闭编辑
            handleCloseEdit () {
                // 判断内容是否修改，没修改则直接关闭
                if (this.drawer.type === 'edit') {
                    const editRoleInfo = cloneDeep(this.roleInfo);
                    const editRoleInfoString = JSON.stringify(editRoleInfo);
                    if (editRoleInfoString !== this.roleInfoString) {
                        return new Promise((resolve) => {
                            this.$Modal.confirm({
                                title: this.lang['confirm'],
                                cancelText: this.lang['cancel'],
                                content: '您已经修改了角色信息，是否直接关闭？',
                                onOk: () => {
                                    resolve();
                                }
                            });
                        });
                    }
                }
            },
            // 添加角色
            handleOpenCreate () {
                this.roleInfo = {
                    id: '',
                    roleName: '',
                    roleCode: '',
                    roleDescrib: '',
                    menu_list: []
                };
                this.drawer.type = 'new';
                this.drawer.show = true;
                this.handleInitRoleInfoForm();
            },
            handleSubmitEdit () {
                this.$refs.roleInfoForm.validate(valid => {
                    if (valid) {
                        if (this.submitting) return;
                        this.submitting = true;
                        this.$api.Role.update(this.roleInfo).then(res => {
                            this.submitting = false;
                            this.drawer.show = false;
                            this.handleClearSelect();
                            this.handleChangePage(1);
                        })
                    }
                });
            },
            handleSubmitNew () {
                if (this.submitting) return;
                this.$refs.roleInfoForm.validate(valid => {
                    if (valid) {
                        if (this.submitting) return;
                        this.submitting = true;
                        this.$api.Role.add(this.roleInfo).then(res => {
                            this.submitting = false;
                            this.drawer.show = false;
                            this.handleClearSelect();
                            this.handleChangePage(1);
                        })
                    }
                })
            },
            // 打开分配权限
            handleOpenMenu (id) {
                this.roleInfo = cloneDeep(this.handleGetRole(id));
                this.roleInfoString = JSON.stringify(this.roleInfo);
                this.roleMenuList = cloneDeep(this.menuList);
                this.selectedMenuIds = [];
                let condition ="roleId="+this.roleInfo.id
                this.$api.AccountPrivilege.query({condition}).then(records => {
                    if (records && records.length> 0) {
                        records.map(r=>{
                            this.selectedMenuIds.push(r.menuId)
                        })
                    }
                    this.roleMenuList = this.initSelectedNode(this.roleMenuList, this.selectedMenuIds,[]);
                    this.toggleExpand = true;
                    this.initToggleExpandAll(true);
                    this.modal.show = true;
                })
            },

            // 展开所有树
            initToggleExpandAll (status) {
                this.toggleExpand = status;
                this.roleMenuList = this.initToggleExpandNode(this.roleMenuList, status, []);
            },

             /**
             * @description 递归状态
             * @param {Array} menuList 原数据
             * @param {Boolean} isExpand 是否展开
             * @param {Array} lastList 递归数据
             * */
            initToggleExpandNode (menuList, isExpand,lastList) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    newMenu.expand = isExpand;
                    if (menu.children && menu.children.length) newMenu.children = [];
                    lastList.push(newMenu);
                    menu.children && this.initToggleExpandNode(menu.children, isExpand,newMenu.children);
                });
                return lastList;
            },

            initSelectedNode (menuList, ids, lastList) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    let id = ids.filter(id => id==newMenu.id);
                    if(id.length>0){
                        newMenu.checked = true;
                    }else{
                        newMenu.checked = false;
                        this.toggleSelectAll = false;
                    }
                    if (menu.children && menu.children.length) newMenu.children = [];
                    lastList.push(newMenu);
                    menu.children && this.initSelectedNode(menu.children, ids, newMenu.children);
                });
                return lastList;
            },
            // 判断是否已经全选，更新toggleSelectAll状态
            handleCheckSelectAllStatus (menuList, checkedList) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    if (!newMenu.checked) checkedList.push(newMenu);
                    if (menu.children && menu.children.length) newMenu.children = [];
                    menu.children && this.handleCheckSelectAllStatus(menu.children, newMenu.children);
                });
                return checkedList;
            },
            // 展开所有树
            handleToggleExpandAll (status, checkChecked = false) {
                this.toggleExpand = status;
                this.roleMenuList = this.handleToggleExpandNode(this.roleMenuList, status, checkChecked, []);
            },
            /**
             * @description 递归状态
             * @param {Array} menuList 原数据
             * @param {Boolean} isExpand 是否展开
             * @param {Boolean} checkChecked 是否选中
             * @param {Array} lastList 递归数据
             * */
            handleToggleExpandNode (menuList, isExpand, checkChecked, lastList) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    newMenu.expand = isExpand;
                    if (checkChecked) {
                        const roleMenuList = [...this.roleInfo.menu_list];
                        newMenu.checked = !!roleMenuList.find(item => item === newMenu.id);
                    }
                    if (menu.children && menu.children.length) newMenu.children = [];

                    lastList.push(newMenu);
                    menu.children && this.handleToggleExpandNode(menu.children, isExpand, checkChecked, newMenu.children);
                });
                return lastList;
            },
            // 全选/全取消
            handleToggleSelectAll (status) {
                this.toggleSelectAll = status;
                this.roleMenuList = this.handleToggleSelectAllNode(this.roleMenuList, status, []);
            },
            /**
             * @description 全选/全取消
             * @param {Array} menuList 原数据
             * @param {Boolean} isSelectAll 是否全选
             * @param {Array} lastList 递归数据
             * */
            handleToggleSelectAllNode (menuList, isSelectAll, lastList) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    newMenu.checked = isSelectAll;
                    if (menu.children && menu.children.length) newMenu.children = [];

                    lastList.push(newMenu);
                    menu.children && this.handleToggleSelectAllNode(menu.children, isSelectAll, newMenu.children);
                });
                return lastList;
            },
            // 获取菜单数据
            handleGetMenuList () {
                this.getMenuList();
            },
            //通过服务端请求获取菜单列表
            getMenuList () {
                // 下面的 params 是获取的表单查询参数
                this.menuDataList = [];
                let condition = "";
                if (this.query != null && this.query != "") {
                    condition+="menuName like '"+this.query+"'";
                }
                this.$api.Menu.query({condition}).then(res => {
                    this.menuDataList = [];
                    let records = cloneDeep(res);
                    if (records && records.length > 0) {
                        records.forEach(item => {
                            let tempMenuData = {
                                id: item.id,
                                createTime: item.createTime,
                                updateTime: item.updateTime,
                                title: item.menuName,
                                subtitle: item.menuTitle,
                                path: item.menuUrl,
                                icon: item.showPic,
                                auth: '',
                                target: '_self',
                                divided: false,
                                name: item.fatherMenuId == "" ? newObj.menuName : "",
                                header: item.fatherMenuId,
                                fatherMenuId: item.fatherMenuId,
                                sysId: item.sysId,
                                menuNum: item.menuNum,
                                menuPath: item.menuPath,
                            };
                            this.menuDataList.push(tempMenuData);
                        })
                        this.buildMenuDataList();
                        this.sourceMenuList = this.menuList;
                        this.handleToggleExpandAll(true);
                        this.loading = false;
                    }
                }).finally(()=>{
                    this.loading = false;
                });
            },
            //构建菜单数据列表
            buildMenuDataList(){
                this.menuDataList.sort((a, b) => a.menuNum - b.menuNum);
                let topMenuList = this.menuDataList.filter(item => item.fatherMenuId == "" || item.fatherMenuId==null);
                if(topMenuList!=null && topMenuList.length > 0){
                    topMenuList.forEach(menu => {
                        this.buildChildrenMenuList(menu);
                    })
                }
                this.menuList = cloneDeep(topMenuList);
            },
            //构建子菜单列表
            buildChildrenMenuList(topMenu){
                let childrenMenuList = this.menuDataList.filter(item => item.fatherMenuId == topMenu.id);
                if(childrenMenuList !=null && childrenMenuList.length > 0){
                    topMenu.children = childrenMenuList;
                    topMenu.children.forEach(menu => {
                        this.buildChildrenMenuList(menu);
                    })
                }
            },
            handleCheckNode (items) {
                this.selectedMenuData = items;
            },
            handleGetMenuIds (menuList, ids) {
                menuList.forEach(menu => {
                    let newMenu = {};
                    for (let i in menu) {
                        if (i !== 'children') newMenu[i] = cloneDeep(menu[i]);
                    }
                    if (newMenu.checked) ids.push(newMenu.id);
                    if (menu.children && menu.children.length) newMenu.children = [];
                    menu.children && this.handleGetMenuIds(menu.children, ids);
                });
                return ids;
            },
            handleSubmitPermission(){
                let  menuIds = this.handleGetMenuIds(this.roleMenuList, []);
                let condition = "roleId="+this.roleInfo.id;
                let records = [];
                menuIds.map(id=>{
                    records.push({roleId:this.roleInfo.id,menuId:id})
                })
                if (this.submitting) return;
                this.submitting = true;
                this.$api.AccountPrivilege.firstDeleteAndAdd(condition,records).then(res => {
                    this.submitting = false;
                    this.modal.show = false;
                })
            },
        },
        mounted () {
            this.initElementHeight();
            this.handleGetMenuList();
        }
    }
</script>
<style lang="less">
    .page-sys-role{
        &-drawer{
            &-footer{
                width: 100%;
                position: absolute;
                bottom: 0;
                left: 0;
                border-top: 1px solid #e8e8e8;
                padding: 10px 16px;
                text-align: right;
                background: #fff;
            }
        }
    }
</style>
